package com.software.car.handler;

import com.aliyun.oss.OSSException;
import com.software.car.common.enums.ResultEnum;
import com.software.car.common.exception.BaseException;
import com.software.car.common.utils.CommonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.stereotype.Repository;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.time.LocalDateTime;

/**
 * @Author 魔法はまだ解けない
 * @Date 2021/1/21
 */
@Repository
@RestControllerAdvice
public class ExceptionHandler {
    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 将自定义异常记录日志内
     *
     * @param e
     * @return
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(BaseException.class)
    @ResponseStatus(HttpStatus.OK)
    public CommonResult badRequestException(BaseException e) {
        logger.info("---自定义异常：");
        printLog(e);
        return CommonResult.fail(e.getExceptionEnum());
    }

    /**
     * 将系统出现的所有未知异常记录日志内
     *
     * @param e
     * @return
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public CommonResult error(Exception e) {
        logger.info("---未知异常：");
        printLog(e);
        return CommonResult.fail(ResultEnum.EXCEPTION);
    }

    /**
     * 处理参数异常
     *
     * @param e
     * @return
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.OK)
    public CommonResult requestParamError(Exception e) {
        logger.info("---未知异常：");
        printLog(e);
        return CommonResult.fail(ResultEnum.PARAMS_ERROR);
    }

    /**
     * 处理参数异常
     *
     * @param e
     * @return
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(DataIntegrityViolationException.class)
    @ResponseStatus(HttpStatus.OK)
    public CommonResult dataTooLong(Exception e) {
        logger.info("---数据异常：");
        printLog(e);
        return CommonResult.fail(ResultEnum.PARAMS_ERROR);
    }

    /**
     * insert执行异常
     *
     * @param e
     * @return
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(DuplicateKeyException.class)
    @ResponseStatus(HttpStatus.OK)
    public CommonResult sqlError(Exception e) {
        logger.info("---异常：");
        printLog(e);
        return CommonResult.fail(ResultEnum.INSERT_FAIL);
    }

    /**
     * 阿里云异常
     * objectName也就是url不正确或者oss上面不存在该文件.
     *
     * @param e
     * @return
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(OSSException.class)
    @ResponseStatus(HttpStatus.OK)
    public CommonResult ossError(Exception e) {
        logger.info("---异常：");
        printLog(e);
        return CommonResult.fail(ResultEnum.OSS_EXCEPTION);
    }

    /**
     * 参数异常
     * 前端传递的HTTP请求参数异常
     *
     * @param e
     * @return
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.OK)
    public CommonResult requestError(Exception e) {
        logger.info("---异常：");
        printLog(e);
        return CommonResult.fail(ResultEnum.REQUEST_PARAMETER_EXCEPTION);
    }

    /**
     * 请求方式异常
     * objectName也就是url不正确或者oss上面不存在该文件.
     *
     * @param e
     * @return
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.OK)
    public CommonResult requestMethodError(Exception e) {
        logger.info("---异常：");
        printLog(e);
        return CommonResult.fail(ResultEnum.REQUEST_METHOD_EXCEPTION);
    }
    /**
     *
     * 参数校验错误
     *
     * @param e
     * @return
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.OK)
    public CommonResult paramException(Exception e) {
        logger.info("---异常：");
        printLog(e);
        return CommonResult.fail(e.getMessage());
    }


    void printLog(Exception e) {
        //获取异常信息printLog
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        e.printStackTrace(new PrintStream(baos));
        //记录异常信息
        logger.info("异常时间：" + LocalDateTime.now().toString());
        logger.info("异常信息：" + baos.toString());
    }
}
